﻿#include "PacketParse.h"
#include "Net.h"
#include "ServerHelp2.h"
#include <arpa/inet.h>
#include "MemoryPoolObj.h"
#include "SendThreadPool.h"

#include "cmd.h"

#include "UCommon.h"          //gettimeofday


#define PROTO_ENC 1
using  namespace std;


CPacketParse* CPacketParse::pPacketObj = nullptr;

std::mutex CPacketParse::mutex_p;

CPacketParse::GCp  CPacketParse::gcp;


CPacketParse::CPacketParse()
{

}

unsigned short		CPacketParse::BLEndianUshort(unsigned short value)
{
	return ((value & 0x00FF) << 8) | ((value & 0xFF00) >> 8);
}
unsigned short CPacketParse::CheckSumHeader(unsigned char* memTcpHeader, int nLen)
{
	unsigned char* data = (unsigned char*)memTcpHeader;

	unsigned short uCheck = 0;
	while (nLen-- > 0)
	{
		uCheck ^= *data++;
	}
	return  uCheck;
}

void  CPacketParse::ParseCmd(char *pMsgBufIn)
{
    STRUC_MSG_HEADER  *pMsgHeaderIn    = (STRUC_MSG_HEADER*)pMsgBufIn;                                //消息头
    NET_TCP_HEAD  *memTcpIn           = (NET_TCP_HEAD*)(pMsgBufIn + g_TcpMsgSize);                      //包头
    //-----------------------------check  data
	unsigned char* cCheckBegin = (unsigned char*)memTcpIn;
	cCheckBegin += 2;
	int sDataLen = BLEndianUshort(memTcpIn->sDataLen);

	unsigned short uCheck = CheckSumHeader(cCheckBegin, sDataLen + g_TcpHeaderSize-2);

	typedef union uData 
	{
		unsigned short uValue;
		unsigned char sBuff[2];
	}uData;
	uData  struct0;
	
	unsigned char* cCheck = (unsigned char*)memTcpIn;
	struct0.sBuff[0] = cCheck[0];
	struct0.sBuff[1] = cCheck[1];
	
#ifndef  EPOLL_ET
	UCommon::BigSmall(memTcpIn);
#endif
    sClient*p_Conn = pMsgHeaderIn->p_Conn;                                  //消息头中藏着连接池中连接的指针
   
	::printf("check  check :%d %d %d datalen:%d \r\n", uCheck, struct0.uValue, memTcpIn->sCommandId, sDataLen);
	
	if (uCheck != struct0.uValue)
	{
	  ::printf("check  Error uCheck:%d struct0.uValue:%d \r\n", uCheck, struct0.uValue);
      return ;	  
	}

    if (p_Conn->iCurrsequence != pMsgHeaderIn->iCurrsequence)
    {
        return;             //丢弃这种包
    }
    bool    bNeedRespose = true;
    bool    * bNeedSend = &bNeedRespose;

    int nMemSize = 2048;
    switch (memTcpIn->sCommandId)
    {
    case  Cmd_DeviceLogin:
    {

    }
    break;
    default:
        //nMemSize = 60960;
		nMemSize = 4096;
    }
    char* pMsgBufOut = (char*)MemPoolObj::GetMemoryPool()->Malloc(g_TcpMsgSize + g_TcpHeaderSize + nMemSize);
    memcpy(pMsgBufOut, (char*)pMsgHeaderIn, g_TcpMsgSize);												        //设置消息头

    NET_TCP_HEAD * memTcpOut = (NET_TCP_HEAD *)(pMsgBufOut + g_TcpMsgSize);		    //指向发送包头

    memcpy(memTcpOut, (char*)memTcpIn, g_TcpHeaderSize);                                                       //设置包头
	Error_Code_IOT eCode = code_Faild_IOT;

#ifdef MY_DEBUG
	SYSTEMTIME sys;
	UCommon::GetLocalTime(sys);

	char szLogIn[256] = { 0 };
	sprintf(szLogIn, "devid:%d,Command:%04X-->", memTcpIn->nDevID, memTcpIn->sCommandId);
	::printf(szLogIn);

#endif
#ifdef MY_OUT
	map<CMD_TYPE_IOT, string>::iterator it = g_pServer->m_mapCmd.find((CMD_TYPE_IOT)memTcpIn->sCommandId);
	string strCommand = "";
	if (it != g_pServer->m_mapCmd.end())
	{
		strCommand = (string)it->second;
		SYSTEMTIME sys;
		UCommon::GetLocalTime(sys);
		char szLogIn[256] = { 0 };
		sprintf(szLogIn, "%4d-%02d-%02d %02d:%02d:%02d:%s In-->", sys.wYear, sys.wMonth, sys.wDay, sys.wHour, sys.wMinute, sys.wSecond, strCommand.c_str());
		::printf(szLogIn);
	}
#endif

	Log_Device  Log;
	AbsWorker* pWork = (AbsWorker*) g_pServer->m_mapWorkObj[(CMD_TYPE_IOT)memTcpIn->sCommandId];
	if (pWork)
	{
		pWork->DoWork(memTcpIn, memTcpOut, g_pServer, p_Conn, bNeedSend,Log);
	}
	else
	{
		#ifdef MY_OUT
				printf(" Command Not Handle:%d-->\n", memTcpIn->sCommandId);
				char szOut[128] = { 0 };
				sprintf(szOut, "IP:%s,Command:%d NotFind:%d\n", p_Conn->m_szIp, memTcpIn->sCommandId, eCode);
				printf("%s\n", szOut);	
				bNeedRespose = false;				
		#endif
	}

    if (bNeedRespose == true)
    {
		UCommon::BigSmall(memTcpOut);
		CSendThreadPool::GetInstance()->AddTask(p_Conn->nThreadID,pMsgBufOut);
    }
	else
	{
		printf("Not response\r\n");
		MemPoolObj::GetMemoryPool()->Free(pMsgBufOut);
		pMsgBufOut = nullptr;
	}
}

CPacketParse* CPacketParse::GetObject()
{
    static CPacketParse cPacketParse;
    return &cPacketParse;
}

CPacketParse* CPacketParse::GetInstance()
{
	if (pPacketObj == nullptr)			 //指针为空，则创建管理器
	{
		std::lock_guard<std::mutex> lock(mutex_p);
		if (pPacketObj == nullptr)		 //双重检测
		{
			pPacketObj = new CPacketParse();
		}
	}
	return pPacketObj;
}
